package com.ross.web.transaction;

import java.awt.Desktop;
import java.io.DataInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Comparator;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;

import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;

import net.sf.jasperreports.engine.JRDataSourceProvider;
import net.sf.jasperreports.engine.JRField;
import net.sf.jasperreports.engine.JasperCompileManager;
import net.sf.jasperreports.engine.JasperExportManager;
import net.sf.jasperreports.engine.JasperFillManager;
import net.sf.jasperreports.engine.JasperPrint;
import net.sf.jasperreports.engine.JasperReport;
import net.sf.jasperreports.engine.data.JRBeanCollectionDataSource;
import net.sf.jasperreports.view.JasperViewer;

import org.apache.struts2.ServletActionContext;

import com.opensymphony.xwork2.ActionSupport;
import com.ross.web.DTO.ProductDTO;
import com.ross.web.dao.AuditLogDAO;
import com.ross.web.dao.CustomersDAO;
import com.ross.web.dao.OrdersDAO;
import com.ross.web.dao.ProductDAO;
import com.ross.web.dao.SoldProductsDAO;
import com.ross.web.domain.AuditLog;
import com.ross.web.domain.Customers;
import com.ross.web.domain.Orders;
import com.ross.web.domain.Product;
import com.ross.web.domain.SoldProducts;
import com.ross.web.domain.Users;
import com.ross.web.util.DateUtil;
import com.ross.web.util.SessionLogout;
import com.sun.jmx.snmp.UserAcl;

public class SellProductAction extends ActionSupport {
	
	private TreeMap<String,ProductDTO> productDTOList = new TreeMap<String,ProductDTO>();
	private Product product;
	private int customer_id;
	private List<Customers> customersList;
	private String name;
	private ProductDTO productDTO = new ProductDTO();
	private ProductDAO productDAO = new ProductDAO();
	private int prodId;
	private String barcode;
	private int quantity;
	private String task;
	private String grandTotal;
	private String cash;
	private String amountchange;
	
	private HttpServletRequest request;
	
	
	
	//receipt
	private HashMap jParam;
	private List<ProductDTO> forReceiptList;
	private InputStream fileStream;
	private String isreceipt;
	
	SessionLogout sessionLogout = new SessionLogout();
	
	//dao
	SoldProductsDAO soldProductsDAO = new SoldProductsDAO();
	OrdersDAO ordersDAO = new OrdersDAO();
	CustomersDAO customerDAO = new CustomersDAO();
	public String goToSellProducts(){
		
		if (sessionLogout.SessionExpired()) {
			addActionMessage("Session already expired");
			return "sessionExpired";
		}
		
		request = ServletActionContext.getRequest();
		
		int i = productDAO.getAllProductOutofStock().size();
		
		if(i>0){
			request.getSession().setAttribute("warning", "show");
		}else{
			request.getSession().setAttribute("warning", "hide");
		}
		
		setGrandTotal(null);
		setAmountchange(null);
		setCash(null);
		setProductDTOList(null);
		request.getSession().removeAttribute("productDTOList");
		setIsreceipt("0");
		return SUCCESS;
	}
	
	public String addToCartAction(){
		try{
		System.out.println("task= "+getTask());
		
		if (sessionLogout.SessionExpired()) {
			addActionMessage("Session already expired");
			return "sessionExpired";
		}
		
		if(!validateInputs()){
			return ERROR;
		}
		
		if(getTask().equals("addToCartAction")){
		request = ServletActionContext.getRequest();
		product = productDAO.getProductByBarCode(getBarcode());
		
		if(product == null){
			addActionError(getText("error.sellproduct.notexist"));
			productDTOList = (TreeMap<String, ProductDTO>) request.getSession().getAttribute("productDTOList");
			getTotal();
			if(request.getSession().getAttribute("cash") != null){
				cash = (String) request.getSession().getAttribute("cash");
				amountchange = getChange(Double.valueOf(cash), Double.valueOf(getTotal()));
			}
			setIsreceipt("0");
			return ERROR;
			
		}
		
		productDTO.setBarcode(product.getBarcode());
		productDTO.setName(product.getName());
		productDTO.setPrice(product.getPrice());
		productDTO.setQuantity(1);
			
		if(request.getSession().getAttribute("productDTOList") == null){
			productDTOList.put(productDTO.getName()+productDTO.getBarcode(),productDTO);
			request.getSession().setAttribute("productDTOList", productDTOList);
		}else{
			productDTOList = (TreeMap<String, ProductDTO>) request.getSession().getAttribute("productDTOList");
			ProductDTO prodDTO = productDTOList.get(productDTO.getName()+productDTO.getBarcode());
				if(prodDTO == null){
					productDTOList.put(productDTO.getName()+productDTO.getBarcode(), productDTO);
				}else{
					productDTO.setQuantity(prodDTO.getQuantity() + productDTO.getQuantity());
					productDTOList.put(productDTO.getName()+productDTO.getBarcode(),productDTO);
				}
				
			request.getSession().setAttribute("productDTOList", productDTOList);
		}
			getTotal();
		
		}
		
		if(request.getSession().getAttribute("cash") != null){
			cash = (String) request.getSession().getAttribute("cash");
			amountchange = getChange(Double.valueOf(cash), Double.valueOf(getTotal()));
		}
			
		}catch(Exception e){
			e.printStackTrace();
		}
		setIsreceipt("0");
		return SUCCESS;
	}
	
	private boolean validateInputs(){
		
		if(productDAO.getAllProductValidated(getBarcode()).size() < 1 ){
			addActionError(getText("error.sellproduct.outofstock"));
		}
		
		
		if(productDAO.getAllProductByExpiry(getBarcode()).size() < 1 ){
			addActionError(getText("error.sellproduct.expiredproduct"));
		}
		
		
		
		
		if(this.hasActionErrors()){
			return false;
		}else{
			return true;
		}
	}

	public String changeQuantityAction(){
		
		if (sessionLogout.SessionExpired()) {
			addActionMessage("Session already expired");
			return "sessionExpired";
		}
		
		if(getTask().equals("changeQuantityAction")){
		
		request = ServletActionContext.getRequest();
		productDTOList = (TreeMap<String, ProductDTO>) request.getSession().getAttribute("productDTOList");
		if(quantity == 0){
			Product p = productDAO.getProductByBarCode(getBarcode());
			productDTOList.remove(p.getName()+getBarcode());
		}else{
		Product p = productDAO.getProductByBarCode(getBarcode());
		productDTO = productDTOList.get(p.getName()+getBarcode());
		productDTO.setQuantity(quantity);
		
		productDTOList.put(productDTO.getName()+getBarcode(), productDTO);
		
		}
		request.getSession().setAttribute("productDTOList", productDTOList);
		
		getTotal();
		
		if(request.getSession().getAttribute("cash") != null){
			cash = (String) request.getSession().getAttribute("cash");
			amountchange = getChange(Double.valueOf(cash), Double.valueOf(getTotal()));
		}	
		
		}
		setIsreceipt("0");
		return SUCCESS;
	}

	public String getChangeAction(){
		
		if (sessionLogout.SessionExpired()) {
			addActionMessage("Session already expired");
			return "sessionExpired";
		}
		
		request = ServletActionContext.getRequest();
		productDTOList = (TreeMap<String, ProductDTO>) request.getSession().getAttribute("productDTOList");
		
		if(cash.equals("")){
			cash = "0";
		}
		
		request.getSession().setAttribute("cash", cash);
		
		amountchange = getChange(Double.valueOf(cash), Double.valueOf(getTotal()));
		grandTotal = getTotal();
		
		setIsreceipt("0");
		return SUCCESS;
	}
	
	public String selectCustomerForOrderAction(){
		if (sessionLogout.SessionExpired()) {
			addActionMessage("Session already expired");
			return "sessionExpired";
		}
		
		try {
			
			customersList = customerDAO.getAllCustomers();
			
		} catch (Exception e) {
			e.printStackTrace();
		}
		
		return SUCCESS;
	}
	
	public String searchCustomerAction(){
		if (sessionLogout.SessionExpired()) {
			addActionMessage("Session already expired");
			return "sessionExpired";
		}
		
		try {
			System.out.println("rossname"+name);
			customersList = customerDAO.getAllCustomersByName(name);
			
		} catch (Exception e) {
			e.printStackTrace();
		}
		
		return SUCCESS;
	}
	
	public String forOrderProductsAction(){
		if (sessionLogout.SessionExpired()) {
			addActionMessage("Session already expired");
			return "sessionExpired";
		}
		
		try{
			
			request = ServletActionContext.getRequest();
			productDTOList = (TreeMap<String, ProductDTO>) request.getSession().getAttribute("productDTOList");
			String allproducts = "";
			double ordergrandtotal = 0;
			Collection<ProductDTO> col = productDTOList.values();
			Iterator<ProductDTO> it = col.iterator();
			ProductDTO productDTOx;
			while(it.hasNext()){
				productDTOx = it.next();
				if(productDTOx.getBarcode() != ""){
					allproducts+= "-" + productDTOx.getName() + "-" + productDTOx.getQuantity() + "-" + productDTOx.getTotalPriceString();
					ordergrandtotal = ordergrandtotal + (productDTOx.getQuantity() * productDTOx.getTotalPrice());
				}
			}
			
			Users ua = (Users) request.getSession().getAttribute("userAccess");
			Customers c = new Customers();
			c = customerDAO.getCustomersById(customer_id);
			
			Orders o = new Orders();
			o.setAllproducts(allproducts);
			o.setOrderdate(DateUtil.getDateToday());
			o.setOrdertime(DateUtil.getTimeToday());
			o.setConfirmdate("");
			o.setConfirmtime("");
			o.setOrdergrandtotal(ordergrandtotal);
			o.setIsconfirmed("NO");
			o.setCustomer_id(customer_id);
			o.setCustomer(c);
			
			ordersDAO.insert(o);
			
			//sold products
			productDAO = new ProductDAO();
			Product p = new Product();
			col = productDTOList.values();
			it = col.iterator();
			while(it.hasNext()){
				SoldProducts sp = new SoldProducts();
				productDTOx = it.next();
				p = productDAO.getProductByBarCode(productDTOx.getBarcode());
				sp.setSolddate(DateUtil.getDateToday());
				if(soldProductsDAO.getSoldProductsByProdId(p.getProdId()) != null){
					SoldProducts sp2 = soldProductsDAO.getSoldProductsByProdId(p.getProdId());
					int units = sp2.getUnits() + productDTOx.getQuantity();
					sp2.setUnits(units);
					sp2.setProdId(p.getProdId());
					sp2.setProdname(p.getName());
					sp2.setProduct(p);
					sp2.setSolddate(DateUtil.getDateToday());
					soldProductsDAO.update(sp2);
					
				}else{
					sp.setUnits(productDTOx.getQuantity());
					sp.setProdId(p.getProdId());
					sp.setProduct(p);
					sp.setProdname(p.getName());
					soldProductsDAO.insert(sp);
				}
				
				Users u = (Users) request.getSession().getAttribute("userAccess");
				String templatePath = request.getSession().getServletContext().getRealPath("/") + "reporttemplates\\receipt.jrxml";
				String destinationPath = request.getSession().getServletContext().getRealPath("/") + "reporttemplates";
				JasperReport jasperReport;
				JasperPrint jasperPrint;
				HashMap jParam = new HashMap<>();
				jParam.put("grandtotal", Double.valueOf(getTotal()));
				jParam.put("cash", getCash());
				jParam.put("change", getChange(Double.valueOf(getCash()), Double.valueOf(getTotal())));
				jParam.put("datetoday", DateUtil.getDateToday());
				jParam.put("timetoday", DateUtil.getTimeToday());
				jParam.put("soldby", u.getFirstname() + " " + u.getMiddlename().substring(0,1) + ". " + u.getLastname());
				
				List<ProductDTO> forReceiptList = new ArrayList<>(productDTOList.values());
				jasperReport = JasperCompileManager.compileReport(templatePath);
				JRBeanCollectionDataSource jbc = new JRBeanCollectionDataSource(forReceiptList);
				jasperPrint = JasperFillManager.fillReport(jasperReport, jParam, new JRBeanCollectionDataSource(forReceiptList,false));
				JasperExportManager.exportReportToPdfFile(jasperPrint, destinationPath+"\\receipt.pdf");
				
			}
			
			
		}catch(Exception e){
			e.printStackTrace();
		}
		
		setIsreceipt("1");
		setGrandTotal(null);
		setAmountchange(null);
		setCash(null);
		setProductDTOList(null);
		request.getSession().removeAttribute("productDTOList");

		return SUCCESS;
	}
	
	public String sellPrintProductWithReceiptAction(){
		
		if (sessionLogout.SessionExpired()) {
			addActionMessage("Session already expired");
			return "sessionExpired";
		}
		
		request = ServletActionContext.getRequest();
		
		productDTOList = (TreeMap<String, ProductDTO>) request.getSession().getAttribute("productDTOList");
		String al_products = "";
		Collection<ProductDTO> col = productDTOList.values();
		Iterator<ProductDTO> it = col.iterator();
		ProductDTO productDTOx;
		while(it.hasNext()){
			productDTOx = it.next();
			if(productDTOx.getBarcode() != ""){
				al_products+= "-" + productDTOx.getName() + "-" + productDTOx.getQuantity() + "-" + productDTOx.getTotalPriceString();
			}
		}
		
		Users ua = (Users) request.getSession().getAttribute("userAccess");
		
		AuditLog al = new AuditLog();
		
		al.setAl_log_date(DateUtil.getDateToday());
		al.setAl_log_time(DateUtil.getTimeToday());
		al.setAl_user(ua.getFirstname() + " " + ua.getMiddlename().substring(0,1) + ". " + ua.getLastname());
		al.setAl_grand_total(getTotal());
		al.setAl_products(al_products);
		al.setAl_username(ua.getUsername());
		
		AuditLogDAO auditLogDAO = new AuditLogDAO();
		try{
			auditLogDAO.insert(al);
		}catch (Exception e) {
			e.printStackTrace();
		}
		
		try{
		//sold products
		productDAO = new ProductDAO();
		Product p = new Product();
		col = productDTOList.values();
		it = col.iterator();
		while(it.hasNext()){
			SoldProducts sp = new SoldProducts();
			productDTOx = it.next();
			p = productDAO.getProductByBarCode(productDTOx.getBarcode());
			sp.setSolddate(DateUtil.getDateToday());
			if(soldProductsDAO.getSoldProductsByProdId(p.getProdId()) != null){
				SoldProducts sp2 = soldProductsDAO.getSoldProductsByProdId(p.getProdId());
				int units = sp2.getUnits() + productDTOx.getQuantity();
				sp2.setUnits(units);
				sp2.setProdId(p.getProdId());
				sp2.setProdname(p.getName());
				sp2.setProduct(p);
				sp2.setSolddate(DateUtil.getDateToday());
				soldProductsDAO.update(sp2);
				
			}else{
				sp.setUnits(productDTOx.getQuantity());
				sp.setProdId(p.getProdId());
				sp.setProduct(p);
				sp.setProdname(p.getName());
				soldProductsDAO.insert(sp);
			}
			
		}
		}catch (Exception e) {
			e.printStackTrace();
		}
		try{
			
			Users u = (Users) request.getSession().getAttribute("userAccess");
			String templatePath = request.getSession().getServletContext().getRealPath("/") + "reporttemplates\\receipt.jrxml";
			String destinationPath = request.getSession().getServletContext().getRealPath("/") + "reporttemplates";
			JasperReport jasperReport;
			JasperPrint jasperPrint;
			HashMap jParam = new HashMap<>();
			jParam.put("grandtotal", Double.valueOf(getTotal()));
			jParam.put("cash", getCash());
			jParam.put("change", getChange(Double.valueOf(getCash()), Double.valueOf(getTotal())));
			jParam.put("datetoday", DateUtil.getDateToday());
			jParam.put("timetoday", DateUtil.getTimeToday());
			jParam.put("soldby", u.getFirstname() + " " + u.getMiddlename().substring(0,1) + ". " + u.getLastname());
			
			List<ProductDTO> forReceiptList = new ArrayList<>(productDTOList.values());
			jasperReport = JasperCompileManager.compileReport(templatePath);
			JRBeanCollectionDataSource jbc = new JRBeanCollectionDataSource(forReceiptList);
			jasperPrint = JasperFillManager.fillReport(jasperReport, jParam, new JRBeanCollectionDataSource(forReceiptList,false));
			JasperExportManager.exportReportToPdfFile(jasperPrint, destinationPath+"\\receipt.pdf");
			//JasperViewer.viewReport(jasperPrint);
			
		}catch(Exception e){
			e.printStackTrace();
		}
		
		setIsreceipt("1");
		setGrandTotal(null);
		setAmountchange(null);
		setCash(null);
		setProductDTOList(null);
		request.getSession().removeAttribute("productDTOList");
		return SUCCESS;
	}
	
	public String receiptWindow(){
		try{
			
			request = ServletActionContext.getRequest();
			String destinationPath = request.getSession().getServletContext().getRealPath("/") + "reporttemplates";
			fileStream = new DataInputStream(new FileInputStream(destinationPath+"\\receipt.pdf"));
		}catch(Exception e){
			e.printStackTrace();
		}
		setIsreceipt("0");
		return SUCCESS;
		
	}
	
	public String resetCartAction(){
		if (sessionLogout.SessionExpired()) {
			addActionMessage("Session already expired");
			return "sessionExpired";
		}
		request = ServletActionContext.getRequest();
		setGrandTotal(null);
		setAmountchange(null);
		setCash(null);
		setProductDTOList(null);
		request.getSession().removeAttribute("productDTOList");
		setIsreceipt("0");
		return SUCCESS;
		
	}
	
	private String getTotal(){
				
		double total = 0;
		Collection<ProductDTO> col = productDTOList.values();
		Iterator<ProductDTO> it = col.iterator();
		
		ProductDTO productDTOx;
		while(it.hasNext()){
			productDTOx = it.next();
			if(productDTOx.getBarcode() != ""){
			total += productDTOx.getTotalPrice();
			}
		}
		grandTotal = String.format("%.2f", total);
		
		return grandTotal;
	}
	
	private String getChange(double cash, double gTotal){
		double xchange = 0;
		String finalChange = "";
		
		xchange = cash - gTotal;
		
		finalChange = String.format("%.2f", xchange);
		
		return finalChange;
	}
	
	
	
	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public List<Customers> getCustomersList() {
		return customersList;
	}

	public void setCustomersList(List<Customers> customersList) {
		this.customersList = customersList;
	}

	public int getCustomer_id() {
		return customer_id;
	}

	public void setCustomer_id(int customer_id) {
		this.customer_id = customer_id;
	}

	public String getIsreceipt() {
		return isreceipt;
	}

	public void setIsreceipt(String isreceipt) {
		this.isreceipt = isreceipt;
	}

	public InputStream getFileStream() {
		return fileStream;
	}

	public void setFileStream(InputStream fileStream) {
		this.fileStream = fileStream;
	}

	public HashMap getjParam() {
		return jParam;
	}

	public void setjParam(HashMap jParam) {
		this.jParam = jParam;
	}

	public List<ProductDTO> getForReceiptList() {
		return forReceiptList;
	}

	public void setForReceiptList(List<ProductDTO> forReceiptList) {
		this.forReceiptList = forReceiptList;
	}

	public String getAmountchange() {
		return amountchange;
	}

	public void setAmountchange(String amountchange) {
		this.amountchange = amountchange;
	}

	public String getCash() {
		return cash;
	}

	public void setCash(String cash) {
		this.cash = cash;
	}

	public String getTask() {
		return task;
	}

	public void setTask(String task) {
		this.task = task;
	}

	public TreeMap<String, ProductDTO> getProductDTOList() {
		return productDTOList;
	}

	public void setProductDTOList(TreeMap<String, ProductDTO> productDTOList) {
		this.productDTOList = productDTOList;
	}

	public Product getProduct() {
		return product;
	}

	public void setProduct(Product product) {
		this.product = product;
	}

	public int getProdId() {
		return prodId;
	}

	public void setProdId(int prodId) {
		this.prodId = prodId;
	}

	public int getQuantity() {
		return quantity;
	}

	public void setQuantity(int quantity) {
		this.quantity = quantity;
	}

	public String getGrandTotal() {
		return grandTotal;
	}

	public void setGrandTotal(String grandTotal) {
		this.grandTotal = grandTotal;
	}

	public String getBarcode() {
		return barcode;
	}

	public void setBarcode(String barcode) {
		this.barcode = barcode;
	}
	
	
	
	
	
	
	
	
}
